<template>
  <div class="relative w-full min-w-0 flex flex-row">
    <BubbleMenu v-if="editable" :editor="editor" />
    <div class="w-full flex-1 bg-white">
      <Menu v-if="editable" :editor="editor"></Menu>
      <editor-content id="editor-content" class="px-2 lg:px-4 mx-1 lg:mx-2" :editor="editor" />
    </div>
    <TableOfContent v-if="showAnchor && !isMobile()" :editor="editor" :anchors="anchorsState" :activeAnchor="activeAnchor"
      @active="onActive" />
  </div>
</template>
<script setup>
import { onUnmounted, ref, watch, watchEffect } from 'vue'
import { EditorContent } from '@tiptap/vue-3';
import BubbleMenu from './BubbleMenu.vue';
import Menu from './Menu.vue';
import { useEditor } from './useEditor.ts';
import { isMobile, debounce } from '@/utils/common';
import TableOfContent from './TableOfContent.vue';
import markdown from '../utils/markdown.ts';
import html2canvas from 'html2canvas'
import { saveAs } from 'file-saver'
import i18n from '../i18n/index.ts';
const props = defineProps({
  showAnchor: {
    type: Boolean,
    default: true
  },
  content: {
    type: String,
    default: ''
  },
  anchors: {
    type: Array,
    default: () => []
  },
  editable: {
    type: Boolean,
    default: true
  },
  title: {
    type: String,
    default: '新的文档'
  },
  locale: {
    type: String,
    default: 'zh_CN'
  },
  editorOptions: {
    type: Object,
    default: () => {}
  }
})
const emits = defineEmits(['update:content', 'update:anchors', 'save', 'share', 'export', 'activeAnchor'])
const anchorsState = ref(props.anchors);
const activeAnchor = ref('');
const onActive = (id) => {
  activeAnchor.value = id;
  window.scrollTo({
    top: document.getElementById(id).getBoundingClientRect().top + window.scrollY - 64,
    behavior: 'smooth'
  })
  emits('activeAnchor', id)
}
watchEffect(() => {
  i18n.init(props.locale);
})
const onUpdated = debounce(() => {
  emits('update:content', editor?.value?.getHTML());
}, 300);
const onExport = (type, editor) => {
  switch (type) {
    case 'json': {
      let json = editor.getJSON();
      const blob = new Blob([JSON.stringify(json)], {
        type: 'application/json;charset=utf-8'
      })
      saveAs(blob, `${props.title}.json`)
      break;
    }
    case 'html': {
      let html = editor.getHTML();
      const blob = new Blob([html], {
        type: 'text/html;charset=utf-8'
      })
      saveAs(blob, `${props.title}.html`)
      break;
    }
    case 'docx': {
      editor?.message?.warning(i18n.t("noSupportFile"));
      // let htmlContent = editor.getHTML();
      // 将 HTML 内容转换为 Docx 格式
      // const blob = htmlDocx.asBlob(htmlContent);
      // 使用 saveAs 函数保存文件
      // saveAs(blob, `${props.title}.docx`)
      break;
    }
    case 'markdown': {
      let md = markdown.serialize(editor.view.state.doc);
      const blob = new Blob([md], {
        type: 'text/markdown;charset=utf-8'
      })
      saveAs(blob, `${props.title}.md`)
      break;
    }
    case 'pdf': {
      editor?.message?.warning(i18n.t("notSupportedFile"));
      break;
    }
    case 'image': {
      const wrapEditor = document.getElementById('editor-content');
      if (wrapEditor) {
        // let pageFooter = document.createElement("p");
        // pageFooter.className = "editor-footer"
        // pageFooter.innerText = "http://progress123.online";
        // wrapEditor.appendChild(pageFooter);
        html2canvas(wrapEditor, {
          useCORS: true,
          allowTaint: false
        }).then(function (canvas) {
          canvas.toBlob((blob) => {
            saveAs(blob, `${props.title}.png`);
            // wrapEditor.removeChild(pageFooter);
          })
        })
      }
      break;
    }
    default:
      break;
  }
}

const editor = useEditor({
  editable: props.editable,
  content: props.content,
  onUpdate: onUpdated,
  placeholder: i18n.t("placeholder"),
  onUpdateAnchors: (content) => {
    anchorsState.value = content;
    emits('update:anchors', content)
  },
  onSave: () => {
    emits('save', editor?.value?.getHTML());
  },
  onShare: () => {
    emits('share', editor?.value?.getHTML());
  },
  onExport: (type, editor) => {
    onExport(type, editor)
  },
  ...props.editorOptions
});

watch(() => props.content, (value, oldValue) => {
  if (value === oldValue) return;
  const isSame = editor.value && editor.value.getHTML() === value;
  // JSON
  // const isSame = JSON.stringify(editor.getJSON()) === JSON.stringify(value)
  if (isSame) {
    return;
  };
  editor.value && editor.value.commands.setContent(value || '', true);
})
watch(() => props.editable, (value, oldValue) => {
  if (value === oldValue) {
    return;
  }
  editor.value && editor.value.setEditable(value, false)
  // autofocus
  if (value) {
    editor.value && editor.value.commands.focus();
  }
})
watch(() => props.editorOptions, (value) => {
  editor.value && editor.value.setOptions(value);
})
onUnmounted(() => {
  editor?.value?.destroy()
})
</script>


<style lang='scss' scoped></style>